/**
 * 给定7*7的字符矩阵，有WB两种字母。如果有形如
 * B B
 *  B
 * B B
 * 的构型则称矩阵是不符合要求的。
 * 现在要把矩阵修改为符合要求，最少要改动几个B字母。
 * 
 * 首先分成两个独立的问题看待。
 * 然后考虑将问题看做是一个01矩阵可重复的最小覆盖问题
 * 将每个点看做是一行，如果改动第i个点能够令第j个X失效，
 * 则令Aij=1，否则令Aij=0
 * 于是题目变为了选择最少的行数使得每一列至少有一个1
 * 最小重复覆盖。
 * 耗时31ms，自己手写暴力则是202ms。
 */  
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

const int SIZE = 300;
const int INF = 1000000000;

//上下左右
int Up[SIZE*SIZE],Down[SIZE*SIZE],Right[SIZE*SIZE],Left[SIZE*SIZE];
//所在行列
int Rth[SIZE*SIZE],Cth[SIZE*SIZE];
//每一行的头指针
int RHead[SIZE];
//每一列元素的个数
int CCnt[SIZE];
int toUsed;
int Ans;

//初始化，01矩阵的大小为rows×cols
void init(int rows,int cols){
    fill(CCnt,CCnt+cols+1,0);
    for(int i = 0;i <= cols;++i){
        Up[i] = Down[i] = i;//上下都指向自己
        Left[i+1] = i;
        Right[i] = i+1;
    }
    Right[cols] = 0; Left[0] = cols;
    toUsed = cols;

    RHead[0] = 0;
    fill(RHead+1,RHead+rows+2,-1);
    Ans = INF;
}

//将位置(row,cols)设为1
inline void link(int row,int col){
    ++CCnt[Cth[++toUsed]=col];//指定所在列，并将该列元素个数加1
    Rth[toUsed] = row;        //指定所在行

    Down[toUsed] = Down[col];
    Up[Down[col]] = toUsed;
    Up[toUsed] = col;
    Down[col] = toUsed;  //将节点插入列链表，本质就是链表的头插入

    if(RHead[row] < 0){
        RHead[row] = Left[toUsed] = Right[toUsed] = toUsed;
    }else{
        int const&h = RHead[row];
        Right[toUsed] = Right[h];
        Left[Right[h]] = toUsed;
        Right[Left[toUsed] = h] = toUsed;//将节点插入行链表，本质就是链表的头插入
    }
}

//删除node节点的同列节点
void remove(int node){
    for(int i = Down[node];i != node;i = Down[i])
        Left[Right[i]] = Left[i], Right[Left[i]] = Right[i];
}

//恢复node节点的同列节点
void resume(int node){
    for(int i = Up[node];i != node;i = Up[i])
        Left[Right[i]] = Right[Left[i]] = i;
}

bool Flag[SIZE] = {false};

//评价函数，至少还要删多少次，
int f(){
    int ret = 0;
    //标题行上仍然存在的节点置为true
    for(int i = Right[0]; i != 0;i = Right[i])Flag[i] = true;

    //对于标题行中的每一个节点
    for(int i = Right[0]; i != 0;i = Right[i])if(Flag[i]){
        ret++;
        Flag[i] = false;

        //同一列的行全部置为false，不计数
        for(int j = Down[i];j != i;j = Down[j])for(int k = Right[j];k != j;k = Right[k])
            Flag[Cth[k]] = false;
    }

    return ret;
}

//d已经删除的行数
void dlx(int d){
    if(d + f() >= Ans)return;
    if(Right[0] == 0){
        if(d < Ans)Ans = d;
        return;
    }

    //找列元素最少的列
    int col,tmp = INF;
    for(int i=Right[0];i!=0;i=Right[i]){
        if ( CCnt[i] < tmp && 1 == (tmp = CCnt[col=i]) ) break;
    }

    //对第col列的每一行
    for(int i = Down[col];i != col;i = Down[i]){
        //删除i所在行的全部节点
        remove(i);
        for(int j = Right[i];j != i;j = Right[j])remove(j);

        dlx(d+1);

        //恢复
        for(int j = Left[i];j != i;j = Left[j])resume(j);
        resume(i);
    }
}

using llt = long long;
using vi = vector<int>;
using vll = vector<llt>;
using pii = pair<int, int>;
using vpii = vector<pii>;

template<typename T>
void input(vector<T> & v, int n){
	v.assign(n + 1, 0);
	for(int i=1;i<=n;++i) cin >> v[i];
	return;
}

vpii get(int r, int c) {
	return {{r, c}, {r - 1, c - 1}, {r - 1, c + 1}, {r + 1, c - 1}, {r + 1, c + 1}}; 
}

int f(int r, int c){
    auto t = c + r * 7;
	t >>= 1;
	return t + 1;
}

pii g(int idx, int off=0){
	idx -= 1;
	idx <<= 1;
	return {idx / 7, idx % 7 + off};
}

vector<string> Board(7, string(7, ' '));
vector<vi> X2P;
vector<vi> P2X;

bool isOK(const vpii & v){
	for(const auto & p : v)if('B'!=Board[p.first][p.second])return false;
	return true;
}

int proc(){
	P2X.assign(26, {});
	X2P.clear(); X2P.emplace_back(vi());   
	int r = 1, c = 1, o = 1;
	for(int i=1;i<=13;++i){
        auto ps = get(r, c);
		if(isOK(ps)){
			auto xidx = X2P.size();
			X2P.emplace_back(vi());

            for(const auto & p : ps){
				auto pidx = f(p.first, p.second);
				X2P[xidx].emplace_back(pidx);
				P2X[pidx].emplace_back(xidx);
			}
		}

		c += 2;
		if(c >= 6){
            c = o + 1;
			o ^= 1;
			r += 1;
		}
	}

#ifndef ONLINE_JUDGE
    cout << "OU\n";
    for(int i=1,n=X2P.size();i<n;++i){
		const auto & v = X2P[i];
		if(v.empty()) continue;
		cout << "X" << i << ":";
		for(const auto & p : v){
            auto pp = g(p);
			cout << "(" << pp.first << ", " << pp.second << ")";
		}
		cout << endl;
	}
#endif

    init(25, X2P.size() - 1);
	for(int i=1;i<=25;++i){
		for(auto j : P2X[i]){
            link(i, j);
		}
	}
	dlx(0);
	auto ans = Ans;

	P2X.assign(25, {});
	X2P.clear(); X2P.emplace_back(vi());   

    r = 1, c = 2, o = 0;
	for(int i=1;i<=12;++i){
		// cout << r << ", " << c << endl;
		auto ps = get(r, c);
		if(isOK(ps)){
			auto xidx = X2P.size();
			X2P.emplace_back(vi());
            for(const auto & p : ps){
				auto pidx = f(p.first, p.second);
				X2P[xidx].emplace_back(pidx);
				P2X[pidx].emplace_back(xidx);
			}
		}

		c += 2;
		if(c >= 6){
            c = o + 1;
			o ^= 1;
			r += 1;
		}
	}	

#ifndef ONLINE_JUDGE
    cout << "JI\n";
    for(int i=1,n=X2P.size();i<n;++i){
		const auto & v = X2P[i];
		if(v.empty()) continue;
		cout << "X" << i << ":";
		for(const auto & p : v){
            auto pp = g(p, 1);
			cout << "(" << pp.first << ", " << pp.second << ")";
		}
		cout << endl;
	}
#endif

    init(24, X2P.size() - 1);
	for(int i=1;i<=24;++i){
		for(auto j : P2X[i]){
            link(i, j);
		}
	}
	dlx(0);
    ans += Ans;
	return ans;
}

void work(){
    for(auto & s : Board) cin >> s;
	cout << proc() << "\n";
    return;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int nofkase = 1;
    cin >> nofkase;
    while(nofkase--) {
		work();
	}
    return 0;
}